package com.yanqu.road.server.manager.monopolymarket;

import com.yanqu.road.entity.enums.eMonopolyMarketResType;
import com.yanqu.road.entity.monopolymarket.*;
import com.yanqu.road.entity.monopolymarket.office.*;
import com.yanqu.road.entity.monopolymarket.config.MonopolyMarketResConfigData;
import com.yanqu.road.entity.monopolymarket.office.log.MonopolyMarketOfficeRobLogData;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.bussiness.monopolymarket.MonopolyMarketBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.pb.monopolymarket.MonopolyMarketProto;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.manger.ConfigMgr;
import com.yanqu.road.server.manger.MonopolyMarketCommonMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.utils.date.DateHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @Description 榷署
 * @Author cwq
 * @Data 2021/8/13 16:33
 */
public class MonopolyMarketOfficeMgr {

    public static Logger logger = LogManager.getLogger(MonopolyMarketOfficeMgr.class.getName());


    public static AtomicLong maxResGrabFinishId;
    /**
     * 玩家采集完成的未领取奖励
     */
    public static Map<Long, MonopolyMarketOfficeFinishData> userOfficeFinishMap = new ConcurrentHashMap<>();

    /**
     * 临时采集的奖励 入库用
     */
    public static List<MonopolyMarketOfficeFinishData> tempOfficeFinishList = new ArrayList<>();

    /**
     * 配置  k：资源类型
     */
    public static List<MonopolyMarketResConfigData> resConfigList = new ArrayList<>();

    /**
     * 配置  k：资源等级
     */
    public static Map<Integer,MonopolyMarketResConfigData> resConfigMap = new HashMap<>();

    public static void reloadConfig(){
        List<MonopolyMarketResConfigData> tempResConfigList = new ArrayList<>();
        Map<Integer,MonopolyMarketResConfigData> tempResConfigMap = new HashMap<>();
        for (MonopolyMarketResConfigData item : MonopolyMarketMgr.resConfigList){
            if(item.getType() == eMonopolyMarketResType.OFFICE.getValue()) {
                tempResConfigList.add(item);
                tempResConfigMap.put(item.getLevel(), item);
            }
        }

        resConfigList = tempResConfigList;
        resConfigMap = tempResConfigMap;
    }

    public static void save(MonopolyMarket monopolyMarket){
        // 保存位置
        List<MonopolyMarketOfficeSeatInfo> tempSeatInfo = null;
        synchronized (monopolyMarket.monopolyMarketOffice.updateAndAddSeatInfoSet){
            tempSeatInfo = new ArrayList<>(monopolyMarket.monopolyMarketOffice.updateAndAddSeatInfoSet);
            monopolyMarket.monopolyMarketOffice.updateAndAddSeatInfoSet.clear();
        }
        for (MonopolyMarketOfficeSeatInfo seatInfo : tempSeatInfo){
            if (seatInfo.baseInfo.isUpdateOption()) {
                MonopolyMarketBussiness.updateMonopolyMarketOfficeSeatData(seatInfo.baseInfo);
            } else if (seatInfo.baseInfo.isInsertOption()) {
                MonopolyMarketBussiness.addMonopolyMarketOfficeSeatData(seatInfo.baseInfo);
            }
        }

        List<MonopolyMarketOfficeFinishData> list = null;
        synchronized (tempOfficeFinishList){
            list = new ArrayList<>(tempOfficeFinishList);
            tempOfficeFinishList.clear();
        }
        for(MonopolyMarketOfficeFinishData item : list){
            if (item.isUpdateOption()) {
                MonopolyMarketBussiness.updateMonopolyMarketOfficeFinishData(item);
            } else if (item.isInsertOption()) {
                MonopolyMarketBussiness.addMonopolyMarketOfficeFinishData(item);
            }
        }
    }

    /**
     * 进入大宋榷署 大厅
     * @param page
     * @param time
     * @return
     */
    public static MonopolyMarketProto.MonopolyMarketEnterOfficeRespMsg.Builder enterOffice(int page, long time,long serverId,boolean isGetNoctice) {
        MonopolyMarketProto.MonopolyMarketEnterOfficeRespMsg.Builder builder = MonopolyMarketProto.MonopolyMarketEnterOfficeRespMsg.newBuilder();
        MonopolyMarket monopolyMarket = MonopolyMarketMgr.getMonopolyMarket(serverId,true);
        if(monopolyMarket == null){
            builder.setRet(GameErrorCode.E_SYSTEM_NO_OPEN);
            return builder;
        }
        int startIndex = page * GameConfig.MONOPOLYMARKET_INITIAL_LOADNUM_1;
        int endIndex = startIndex + GameConfig.MONOPOLYMARKET_INITIAL_LOADNUM_1;
        synchronized (monopolyMarket){
            for (int i = startIndex; i < endIndex; i++) {
                if(i >= monopolyMarket.monopolyMarketOffice.seatNum){
                    break;
                }
                MonopolyMarketOfficeSeatInfo seatInfo = monopolyMarket.monopolyMarketOffice.seatInfos[i];
                if(seatInfo != null && (time == 0 || time < seatInfo.baseInfo.getChangeTime())){
                    refreshSeatInfo(monopolyMarket,seatInfo);
                    builder.addSeatList(builderMonopolyMarketOfficeEntity(seatInfo,false));
                }
            }
            if(isGetNoctice){
                MonopolyMarketNoticeData noticeData = MonopolyMarketMgr.getNewMonopolyMarketNoticeData(monopolyMarket,eMonopolyMarketResType.OFFICE.getValue());
                if(noticeData != null){
                    builder.setNewNotice(MonopolyMarketMgr.builderMonopolyMarketNoticeEntity(noticeData));
                }
            }
        }
        builder.setTime(DateHelper.getCurrentSecond());
        builder.setRet(0);
        builder.setPage(page);
        return builder;
    }

    /**
     * 进入大宋榷署 座位
     * @param userId
     * @return
     */
    public static MonopolyMarketProto.MonopolyMarketEnterOfficeSeatRespMsg.Builder enterOfficeSeat(int posIndex, long userId,long serverId) {
        MonopolyMarketProto.MonopolyMarketEnterOfficeSeatRespMsg.Builder builder = MonopolyMarketProto.MonopolyMarketEnterOfficeSeatRespMsg.newBuilder();
        MonopolyMarket monopolyMarket = MonopolyMarketMgr.getMonopolyMarket(serverId,true);
        if(monopolyMarket == null){
            builder.setRet(GameErrorCode.E_SYSTEM_NO_OPEN);
            return builder;
        }
        if(posIndex >= monopolyMarket.monopolyMarketOffice.seatNum){
            builder.setRet(GameErrorCode.E_MONOPOLY_MARKET_OFFICE_SEAT_INFO_NO_EXIST);
            return builder;
        }
        synchronized (monopolyMarket){
            MonopolyMarketOfficeSeatInfo seatInfo = MonopolyMarketOfficeMgr.getMonopolyMarketOfficeSeatInfo(monopolyMarket,posIndex,true);
            refreshSeatInfo(monopolyMarket,seatInfo);
            seatInfo.userMap.add(userId);
            monopolyMarket.monopolyMarketOffice.userInRoomMap.put(userId,posIndex);
            builder.setSeatInfo(builderMonopolyMarketOfficeEntity(seatInfo,true));
        }
        builder.setRet(0);
        return builder;
    }

    /**
     * 退出大宋榷署位置
     * @param userId
     * @return
     */
    public static void exitOfficeSeat(MonopolyMarket monopolyMarket,int index,long userId) {
        MonopolyMarketOfficeSeatInfo seatInfo = monopolyMarket.monopolyMarketOffice.seatMap.get(index);
        if(seatInfo != null){
            seatInfo.userMap.remove(userId);
            monopolyMarket.monopolyMarketOffice.userInRoomMap.remove(userId);
        }
    }

    /**
     * 抢夺/撤回位置
     * @param type   0入座 1撤回
     * @param posIndex
     * @param seatTime
     * @param userId
     * @param serverId
     * @param decorationClass
     * @param decorationOverTime
     * @param userBaseInfo
     * @returnn
     */
    public static MonopolyMarketProto.MonopolyMarketOfficeActionToGameServerMsg.Builder action(int type, int posIndex,int seatTime,long seatUserId,
                                                                                       long userId, long serverId,byte decorationClass, int decorationOverTime,UserBaseInfo userBaseInfo) {
        MonopolyMarketProto.MonopolyMarketOfficeActionToGameServerMsg.Builder builder = MonopolyMarketProto.MonopolyMarketOfficeActionToGameServerMsg.newBuilder();
        builder.setType(type);
        MonopolyMarketProto.MonopolyMarketOfficeActionRespMsg.Builder stcMsg = MonopolyMarketProto.MonopolyMarketOfficeActionRespMsg.newBuilder();
        MonopolyMarket monopolyMarket = MonopolyMarketMgr.getMonopolyMarket(serverId,true);
        if(monopolyMarket == null){
            stcMsg.setRet(GameErrorCode.E_SYSTEM_NO_OPEN);
            builder.setStcMsg(stcMsg);
            return builder;
        }

        MonopolyMarketOfficeRobLogData robLogData = new MonopolyMarketOfficeRobLogData();
        synchronized (monopolyMarket){
            if(!MonopolyMarketCommonMgr.isSystemOpen(monopolyMarket.group, eMonopolyMarketResType.OFFICE.getValue())){
                stcMsg.setRet(GameErrorCode.E_MONOPOLY_MARKET_SYSTEM_NO_OPEN);
                builder.setStcMsg(stcMsg);
                return builder;
            }
            if(posIndex >= monopolyMarket.monopolyMarketOffice.seatNum){
                stcMsg.setRet(GameErrorCode.E_MONOPOLY_MARKET_OFFICE_SEAT_INFO_NO_EXIST);
                builder.setStcMsg(stcMsg);
                return builder;
            }
            MonopolyMarketResConfigData configData = getMonopolyMarketResConfigData(monopolyMarket,posIndex);
            if(configData == null){
                stcMsg.setRet(GameErrorCode.E_MONOPOLY_MARKET_OFFICE_SEAT_CONFIG_NO_EXIST);
                builder.setStcMsg(stcMsg);
                return builder;
            }
            MonopolyMarketOfficeSeatInfo seatInfo = getMonopolyMarketOfficeSeatInfo(monopolyMarket,posIndex,true);
            if(seatInfo.baseInfo.getSeatTime() != seatTime || seatInfo.baseInfo.getUserId() != seatUserId){
                stcMsg.setRet(GameErrorCode.E_MONOPOLY_MARKET_OFFICE_SEAT_INFO_CHANGE);
                builder.setStcMsg(stcMsg);
                return builder;
            }
            int level = MonopolyMarketCommonMgr.calOfficePosLevel(monopolyMarket.monopolyMarketOffice.seatConfigList, seatInfo.baseInfo.getPosIndex());
            int no = calNo(monopolyMarket,posIndex);
            int now = DateHelper.getCurrentSecond();
            boolean isChange = false;
            switch (type){
                case 0:{
                    // 入座
                    if(userBaseInfo == null){
                        stcMsg.setRet(GameErrorCode.E_MONOPOLY_MARKET_USER_DATA_NO_EXIST);
                        builder.setStcMsg(stcMsg);
                        return builder;
                    }
                    // 不能重复入座
                    if(seatInfo.baseInfo.getUserId() == userId){
                        stcMsg.setRet(GameErrorCode.E_MONOPOLY_MARKET_NO_CAN_SEATED_REPEATED_POSITION);
                        builder.setStcMsg(stcMsg);
                        return builder;
                    }
                    boolean success = false;
                    if(seatInfo.baseInfo.getUserId() == 0){
                        success = true;
                        robLogData.setType(0);
                    }else {
                        // pk
                        refreshSeatInfo(monopolyMarket,seatInfo);
                        UserBaseInfo targetUserInfo = CrossUserMgr.getUserBaseInfo(seatInfo.baseInfo.getUserId());

                        robLogData.setStartTime(seatInfo.baseInfo.getSeatTime());
                        robLogData.setUserId(seatInfo.baseInfo.getUserId());
                        robLogData.setDecorationClass(seatInfo.baseInfo.getDecorationClass());
                        robLogData.setTitle(targetUserInfo.getTitleId());
                        robLogData.setPrestige(targetUserInfo.getPrestige());
                        robLogData.setType(1);
                        int pkRounds = 3;
                        if(decorationClass != seatInfo.baseInfo.getDecorationClass()){
                            // 比较称号阶段
                            success = decorationClass > seatInfo.baseInfo.getDecorationClass();
                            pkRounds = 1;
                        } else if(userBaseInfo.getTitleId() != targetUserInfo.getTitleId()){
                            // 比较身份
                            success =  userBaseInfo.getTitleId() > targetUserInfo.getTitleId();
                            pkRounds = 2;
                        } else if(userBaseInfo.getPrestige() != targetUserInfo.getPrestige()){
                            // 比较声望
                            success =  userBaseInfo.getPrestige() > targetUserInfo.getPrestige();
                            pkRounds = 3;
                        }
                        if(success){
                            // 保存被抢记录并通知区服有奖励可领
                            saveFinishRecord(seatInfo.baseInfo.getUserId(),seatInfo,no,level,userBaseInfo.getNickName(),now);
                        }
                        // 通知被抢玩家 加战报 如果成功结算位置信息
                        addOfficeReport(userId,userBaseInfo,seatInfo,targetUserInfo,success,level,no);
                        stcMsg.setPkRounds(pkRounds);
                        stcMsg.setTargetInfo(PlayerBasePb.parsePlayerBaseTempMsg(targetUserInfo));
                        stcMsg.setDecorationOverTime(seatInfo.baseInfo.getDecorationOverTime());
                    }
                    stcMsg.setIsSuccess(success);
                    if(success){
                        // 离开原来位置
                        // 已有位置
                        MonopolyMarketOfficeSeatInfo oldSeatInfo = monopolyMarket.monopolyMarketOffice.userSeatMap.get(userId);
                        if(oldSeatInfo != null){
                            leaveSeatInfo(monopolyMarket,oldSeatInfo,true);
                        }
                        if(configData.getIsad() == 1){
                            // 加公告
                            MonopolyMarketMgr.addNotice(monopolyMarket,eMonopolyMarketResType.OFFICE.getValue(),userId,seatInfo.baseInfo.getUserId(),posIndex);
                        }
                        leaveSeatInfo(monopolyMarket, seatInfo,false);
                        CrossUserMgr.updateUserBaseInfo(userId,userBaseInfo);
                        sitDown(monopolyMarket, userId, now, posIndex,decorationClass,decorationOverTime);
                        stcMsg.setSeatInfo(builderMonopolyMarketOfficeEntity(seatInfo,true));
                    }
                    isChange = success;
                    builder.setSeatLevel(level);
                    builder.setNo(no);

                    robLogData.setIsWin(success);
                    robLogData.setRobId(userId);
                    robLogData.setRobDecorationClass(decorationClass);
                    robLogData.setRobTitle(userBaseInfo.getTitleId());
                    robLogData.setRobPrestige(userBaseInfo.getPrestige());
                    break;
                }
                case 1:
                    // 撤回
                    if(seatInfo.baseInfo.getUserId() != userId){
                        stcMsg.setRet(GameErrorCode.E_MONOPOLY_MARKET_OFFICE_IS_NOT_CURRENTLY_IN_THIS_SEAT);
                        builder.setStcMsg(stcMsg);
                        return builder;
                    }
                    UserBaseInfo targetUserInfo = CrossUserMgr.getUserBaseInfo(seatInfo.baseInfo.getUserId());
                    robLogData.setStartTime(seatInfo.baseInfo.getSeatTime());
                    robLogData.setUserId(seatInfo.baseInfo.getUserId());
                    robLogData.setDecorationClass(seatInfo.baseInfo.getDecorationClass());
                    robLogData.setTitle(targetUserInfo.getTitleId());
                    robLogData.setPrestige(targetUserInfo.getPrestige());
                    robLogData.setType(2);

                    leaveSeatInfo(monopolyMarket, seatInfo,false);
                    isChange = true;
                    stcMsg.setSeatInfo(builderMonopolyMarketOfficeEntity(seatInfo,true));

                    break;
                default:
                    stcMsg.setRet(GameErrorCode.E_MONOPOLY_MARKET_OFFICE_TYPE_ERROR);
                    builder.setStcMsg(stcMsg);
                    return builder;
            }
            if(isChange){
                broadcastMonopolyMarketOfficeRespMsg(seatInfo,userId);
            }

            // 加日志
            robLogData.setGroupId(monopolyMarket.group.getGroupId());
            robLogData.setPosIndex(posIndex);
            robLogData.setLevel(level);
            robLogData.setNo(no);
            robLogData.setLogTime(now);
            MonopolyMarketLogMgr.addMonopolyMarketOfficeRobLogData(robLogData);
        }
        stcMsg.setRet(0);
        builder.setStcMsg(stcMsg);
        return builder;
    }

    /**
     * 初始化 榷署
     * @param monopolyMarket
     */
    public static void initOffice(MonopolyMarket monopolyMarket){
        monopolyMarket.monopolyMarketOffice.seatConfigList = MonopolyMarketCommonMgr.calMonopolyMarketOfficeSeatConfigList(monopolyMarket.group.getServerList().size(),resConfigList,MonopolyMarketMgr.crossConfig.resExtendParamMap);
        monopolyMarket.monopolyMarketOffice.seatNum = calSeatNum(monopolyMarket.monopolyMarketOffice.seatConfigList);
        monopolyMarket.monopolyMarketOffice.seatInfos = new MonopolyMarketOfficeSeatInfo[monopolyMarket.monopolyMarketOffice.seatNum];
        int changeTime = Math.max(monopolyMarket.group.getChangTime(),monopolyMarket.group.getOfficeCfgChangTime());
        List<MonopolyMarketNoticeData> list = MonopolyMarketBussiness.getMonopolyMarketNoticeDataList(MonopolyMarketMgr.getGroupId(monopolyMarket),eMonopolyMarketResType.OFFICE.getValue(), changeTime ,MonopolyMarketMgr.NOTICE_MAX_NUM);
        // 倒序
        Collections.reverse(list);
        monopolyMarket.noticeMap.put(eMonopolyMarketResType.OFFICE.getValue(), list);
        loadDbSeatInfo(monopolyMarket,0);
    }

    /**
     * 离开位置
     * @param seatInfo
     */
    private static void leaveSeatInfo(MonopolyMarket monopolyMarket,MonopolyMarketOfficeSeatInfo seatInfo,boolean isBroadcast){
        monopolyMarket.monopolyMarketOffice.userSeatMap.remove(seatInfo.baseInfo.getUserId());
        resetSeatInfo(monopolyMarket,seatInfo,false);
        seatInfo.baseInfo.setChangeTime(DateHelper.getCurrentSecond());
        synchronized (monopolyMarket.monopolyMarketOffice.updateAndAddSeatInfoSet){
            monopolyMarket.monopolyMarketOffice.updateAndAddSeatInfoSet.add(seatInfo);
        }
        if(isBroadcast){
            broadcastMonopolyMarketOfficeRespMsg(seatInfo,0);
        }
    }

    /**
     * 清空位置信息
     * @param seatInfo
     */
    private static void resetSeatInfo(MonopolyMarket monopolyMarket,MonopolyMarketOfficeSeatInfo seatInfo,boolean isSave){
        seatInfo.baseInfo.setUserId(0);
        seatInfo.baseInfo.setSeatTime(0);
        seatInfo.baseInfo.setDecorationClass((byte)-1);
        seatInfo.baseInfo.setDecorationOverTime(-1);
        seatInfo.baseInfo.setChangeTime(0);
        if(isSave){
            synchronized (monopolyMarket.monopolyMarketOffice.updateAndAddSeatInfoSet){
                monopolyMarket.monopolyMarketOffice.updateAndAddSeatInfoSet.add(seatInfo);
            }
        }
    }

    /**
     * 通过位置获取该位置的信息
     * @param monopolyMarket
     * @param pos
     * @return
     */
    private static MonopolyMarketResConfigData getMonopolyMarketResConfigData(MonopolyMarket monopolyMarket,int pos){
        int type = MonopolyMarketCommonMgr.calOfficePosLevel(monopolyMarket.monopolyMarketOffice.seatConfigList, pos);
        return resConfigMap.get(type);
    }

    /**
     * 通知区服加战报
     * @param attackerId
     * @param attackerInfo
     * @param seatInfo
     * @param defenderInfo
     * @param isWin
     * @param level
     * @param no
     */
    private static void addOfficeReport(long attackerId, UserBaseInfo attackerInfo,MonopolyMarketOfficeSeatInfo seatInfo,UserBaseInfo defenderInfo, boolean isWin,int level,int no){
        MonopolyMarketProto.MonopolyMarketSynAttackToGameServerMsg.Builder builder = MonopolyMarketProto.MonopolyMarketSynAttackToGameServerMsg.newBuilder();
        builder.setType(eMonopolyMarketResType.OFFICE.getValue());
        builder.setRobedId(seatInfo.baseInfo.getUserId());
        builder.setPosIndex(seatInfo.baseInfo.getPosIndex());
        builder.setAttackId(attackerId);
        if(attackerInfo.getServerId() != defenderInfo.getServerId()){
            builder.setAttackInfo(PlayerBasePb.parsePlayerBaseTempMsg(attackerInfo));
        }
        builder.setIsWin(isWin);
        builder.setLevel(level);
        builder.setNo(no);
        MessageHelper.sendPacket(defenderInfo.getServerId(),seatInfo.baseInfo.getUserId(), YanQuMessageUtils.buildMessage(GameProtocol.S_MONOPOLY_MARKET_SYN_ATTACK, builder));
    }


    /**
     * 判断改变位置大小
     * 1 扩容就数据库加载数据  2减少就移除多余数据
     *
     * @param monopolyMarket
     */
    private static void changeSeat(MonopolyMarket monopolyMarket){
        // 判断数量是否相等
        List<MonopolyMarketOfficeSeatConfig> seatConfigList = MonopolyMarketCommonMgr.calMonopolyMarketOfficeSeatConfigList(monopolyMarket.group.getServerList().size(), resConfigList,MonopolyMarketMgr.crossConfig.resExtendParamMap);
        int newSeatNum = calSeatNum(seatConfigList);
        if(monopolyMarket.monopolyMarketOffice.seatNum != newSeatNum){
            logger.info("榷场 榷署位置改变。groupId:{},oldNum：{}, newNum:{}",monopolyMarket.group.getGroupId(),monopolyMarket.monopolyMarketOffice.seatNum,newSeatNum);
            monopolyMarket.monopolyMarketOffice.seatInfos = Arrays.copyOf(monopolyMarket.monopolyMarketOffice.seatInfos, newSeatNum, MonopolyMarketOfficeSeatInfo[].class);
            if(monopolyMarket.monopolyMarketOffice.seatNum < newSeatNum){
                // 如果变大 加载数据库
                loadDbSeatInfo(monopolyMarket, 0);
            }else {
                // 如果缩小 移除多余的位置信息
                for (int i = newSeatNum; i < monopolyMarket.monopolyMarketOffice.seatNum; i++) {
                    monopolyMarket.monopolyMarketOffice.seatMap.remove(i);
                }
            }
            monopolyMarket.monopolyMarketOffice.seatNum = newSeatNum;
            monopolyMarket.monopolyMarketOffice.seatConfigList = seatConfigList;
        }
    }

    /**
     * 数据库加载位置信息
     * @param monopolyMarket
     * @param startIndex
     */
    private static void loadDbSeatInfo(MonopolyMarket monopolyMarket,int startIndex){
        List<MonopolyMarketOfficeSeatData> list = MonopolyMarketBussiness.getMonopolyMarketOfficeSeatInfoList(monopolyMarket.group.getGroupId(),startIndex);
        for(MonopolyMarketOfficeSeatData item : list){
            if(item.getPosIndex() >= monopolyMarket.monopolyMarketOffice.seatNum){
                // 有可能加载的出来数量大于 目前格子的数量
                break;
            }
            if(!monopolyMarket.monopolyMarketOffice.seatMap.containsKey(item.getPosIndex())){
                MonopolyMarketOfficeSeatInfo seatInfo = new MonopolyMarketOfficeSeatInfo(item);
                monopolyMarket.monopolyMarketOffice.seatMap.put(seatInfo.baseInfo.getPosIndex() ,seatInfo);
                monopolyMarket.monopolyMarketOffice.seatInfos[seatInfo.baseInfo.getPosIndex()] = seatInfo;
                if(seatInfo.baseInfo.getUserId() > 0){
                    monopolyMarket.monopolyMarketOffice.userSeatMap.put(seatInfo.baseInfo.getUserId(), seatInfo);
                }
            }
        }
    }

    /**
     * 计算位置编号 从1开始
     * @return
     */
    public static int calNo(MonopolyMarket monopolyMarket,int posIndex){
        int no = 0;
        for(MonopolyMarketOfficeSeatConfig item : monopolyMarket.monopolyMarketOffice.seatConfigList){
            if(posIndex >= item.startIndex && posIndex <= item.endIndex){
                no = posIndex - item.startIndex  + 1;
            }
        }
        return no;
    }


    /**
     * 入座
     * @param monopolyMarket
     * @param userId
     * @param seatTime s
     * @param index
     * @return
     */
    public static MonopolyMarketOfficeSeatInfo sitDown(MonopolyMarket monopolyMarket, long userId,int seatTime, int index,byte decorationClass,int decorationOverTime){
        MonopolyMarketOfficeSeatInfo seatInfo = getMonopolyMarketOfficeSeatInfo(monopolyMarket,index,true);
        seatInfo.baseInfo.setUserId(userId);
        seatInfo.baseInfo.setSeatTime(seatTime);
        seatInfo.baseInfo.setChangeTime(seatTime);
        seatInfo.baseInfo.setDecorationClass(decorationClass);
        seatInfo.baseInfo.setDecorationOverTime(decorationOverTime);

        synchronized (monopolyMarket.monopolyMarketOffice.updateAndAddSeatInfoSet){
            monopolyMarket.monopolyMarketOffice.updateAndAddSeatInfoSet.add(seatInfo);
        }
        monopolyMarket.monopolyMarketOffice.userSeatMap.put(userId, seatInfo);
        return seatInfo;
    }

    private static MonopolyMarketOfficeSeatInfo getMonopolyMarketOfficeSeatInfo(MonopolyMarket monopolyMarket,int index,boolean newIfNull){
        MonopolyMarketOfficeSeatInfo seatInfo = monopolyMarket.monopolyMarketOffice.seatMap.get(index);
        if(seatInfo == null && newIfNull){
            MonopolyMarketOfficeSeatData seatData = new MonopolyMarketOfficeSeatData();
            seatData.setInsertOption();
            seatData.setGroupId(monopolyMarket.group.getGroupId());
            seatData.setPosIndex(index);
            seatInfo = new MonopolyMarketOfficeSeatInfo(seatData);
            monopolyMarket.monopolyMarketOffice.seatInfos[index] = seatInfo;
            monopolyMarket.monopolyMarketOffice.seatMap.put(index,seatInfo);
            synchronized (monopolyMarket.monopolyMarketOffice.updateAndAddSeatInfoSet){
                monopolyMarket.monopolyMarketOffice.updateAndAddSeatInfoSet.add(seatInfo);
            }
        }
        return seatInfo;
    }


    /**
     * 刷新玩家称号
     */
    private static void refreshSeatInfo(MonopolyMarket monopolyMarket,MonopolyMarketOfficeSeatInfo seatInfo){
        if(seatInfo != null && seatInfo.baseInfo.getDecorationOverTime() != -1 && seatInfo.baseInfo.getDecorationOverTime() < DateHelper.getCurrentSecond()){
            seatInfo.baseInfo.setDecorationClass((byte)-1);
            seatInfo.baseInfo.setDecorationOverTime(-1);

            synchronized (monopolyMarket.monopolyMarketOffice.updateAndAddSeatInfoSet){
                monopolyMarket.monopolyMarketOffice.updateAndAddSeatInfoSet.add(seatInfo);
            }
        }
    }

    /**
     * 重置榷署
     * @param monopolyMarket
     */
    public static void resetOffice(MonopolyMarket monopolyMarket){
        MonopolyMarketOfficeMgr.changeSeat(monopolyMarket);
        resetAllSeatInfo(monopolyMarket);
        MonopolyMarketMgr.clearNotice(monopolyMarket,eMonopolyMarketResType.OFFICE.getValue());
    }

    /**
     * 关闭榷署
     * @param monopolyMarket
     */
    public static void closeOffice(MonopolyMarket monopolyMarket){
        resetAllSeatInfo(monopolyMarket);
        MonopolyMarketMgr.clearNotice(monopolyMarket,eMonopolyMarketResType.OFFICE.getValue());
    }

    /**
     * 给房间里面的玩家广播座位信息
     * @param seatInfo
     * @return
     */
    private static void broadcastMonopolyMarketOfficeRespMsg(MonopolyMarketOfficeSeatInfo seatInfo,long excludeId){
        MonopolyMarketProto.BroadcastMonopolyMarketRespMsg.Builder builder = MonopolyMarketProto.BroadcastMonopolyMarketRespMsg.newBuilder();
        builder.setType(0);
        builder.setSeatInfo(builderMonopolyMarketOfficeEntity(seatInfo,true));
        for(long userId : seatInfo.userMap){
            if(userId != excludeId){
                MessageHelper.sendPacket(CrossUserMgr.getServerIdByUserId(userId), userId, YanQuMessageUtils.buildMessage(ClientProtocol.U_MONOPOLY_MARKET_BROADCAST, builder));
            }
        }
    }

    public static int calSeatNum(List<MonopolyMarketOfficeSeatConfig> list){
        int totalNum = 0;
        if(list != null){
            return list.get(list.size() -1).endIndex + 1;
        }
        return totalNum;
    }

    private static MonopolyMarketProto.MonopolyMarketOfficeEntity.Builder builderMonopolyMarketOfficeEntity(MonopolyMarketOfficeSeatInfo seatInfo,boolean showAllPlayer){
        MonopolyMarketProto.MonopolyMarketOfficeEntity.Builder builder = MonopolyMarketProto.MonopolyMarketOfficeEntity.newBuilder();
        builder.setPosIndex(seatInfo.baseInfo.getPosIndex());
        builder.setUserId(seatInfo.baseInfo.getUserId());
        if(seatInfo.baseInfo.getUserId() > 0){
            UserBaseInfo seatUserBaseInfo = CrossUserMgr.getUserBaseInfo(seatInfo.baseInfo.getUserId());
            if(showAllPlayer){
                builder.setUserInfo(PlayerBasePb.parsePlayerBaseTempMsg(seatUserBaseInfo));
            }else {
                builder.setUserInfo(parseSimplePlayerBaseTempMsg(seatUserBaseInfo));
            }
            builder.setDecorationOverTime(seatInfo.baseInfo.getDecorationOverTime());
            builder.setSeatTime(seatInfo.baseInfo.getSeatTime());
        }
        return builder;
    }

    private static void saveFinishRecord(long userId,MonopolyMarketOfficeSeatInfo seatInfo,int no,int level, String robName,int now){
        MonopolyMarketOfficeFinishData officeFinishData = userOfficeFinishMap.get(userId);
        if(officeFinishData == null){
            officeFinishData = new MonopolyMarketOfficeFinishData();
            officeFinishData.setInsertOption();
            officeFinishData.setId(maxResGrabFinishId.incrementAndGet());
            officeFinishData.setUserId(userId);
            officeFinishData.setPosIndex(seatInfo.baseInfo.getPosIndex());
            officeFinishData.setLevel((byte) level);
            officeFinishData.setNo(no);
            officeFinishData.setRobName(robName);
            officeFinishData.setTime(now);
            userOfficeFinishMap.put(userId,officeFinishData);
        }
        synchronized (tempOfficeFinishList){
            tempOfficeFinishList.add(officeFinishData);
        }
    }


    /**
     * 刷新位置
     * @param monopolyMarket
     */
    public static boolean refreshMonopolyMarketOffice(MonopolyMarket monopolyMarket,int time){
        int refreshTime = MonopolyMarketCommonMgr.getResetOfficeTime(time, ConfigMgr.getOfficeEndSecond());
        if(time >= refreshTime && monopolyMarket.group.getOfficeRefreshTime() < refreshTime){
            resetAllSeatInfo(monopolyMarket);
            monopolyMarket.group.setOfficeRefreshTime(time);
            return true;
        }
        return false;
    }

    /**
     * 重置所有位置
     * @param monopolyMarket
     */
    public static void resetAllSeatInfo(MonopolyMarket monopolyMarket){
        for(MonopolyMarketOfficeSeatInfo item : monopolyMarket.monopolyMarketOffice.seatMap.values()){
            resetSeatInfo(monopolyMarket,item,true);
        }
        monopolyMarket.monopolyMarketOffice.userSeatMap.clear();
        monopolyMarket.monopolyMarketOffice.userInRoomMap.clear();
    }


    /**
     * 客户端用来展示玩家信息的数据  不支持点击查看玩家信息
     * @param userBaseInfo
     * @return
     */
    private static PlayerProto.PlayerBaseTempMsg.Builder parseSimplePlayerBaseTempMsg(UserBaseInfo userBaseInfo){
        PlayerProto.PlayerBaseTempMsg.Builder msg = PlayerProto.PlayerBaseTempMsg.newBuilder();
        msg.setNickName(userBaseInfo.getNickName());
        msg.setTitleId(userBaseInfo.getTitleId());
        msg.setDecoration(userBaseInfo.getDecoration());
        msg.setSex(userBaseInfo.getSex());
        msg.setServerId(userBaseInfo.getServerId());
        msg.setWorld(userBaseInfo.getWorld());
        msg.setContinent(userBaseInfo.getContinent());
        msg.setCountry(userBaseInfo.getCountry());
        msg.setProvince(userBaseInfo.getProvince());
        msg.setCity(userBaseInfo.getCity());
        msg.setHideVipAndAddress(userBaseInfo.getHideVipAndAddress());
        return msg;
    }

}
